#include "libORCL/ORCL.h"
#include "libORCL/ORCL_size.h"
#include <getopt.h>

int main(int argc,char** argv){

    // 服务器编号
    int server_num = -1;

    static struct option opts[] = {
        {"server_num", required_argument, 0, 'n'},
    };

    while (1){
        int c = getopt_long(argc, argv, "n:", opts, NULL);

        if (c == -1)
        {
            break;
        }

        switch (c){
            case 'n':
                server_num = atoi(optarg);
                break;
            
            default:
                printf("Invalid argument %d\n", c);
                assert(false);
        }
    }

    assert(server_num>=0);

    // 解析参数，我们现在只加入一个参数就是节点编号，两个进程分布在两个节点上
    // 在两个网卡之间负载均衡
    int port_index = server_num % 2;
    // 绑定的CPU和网卡是反着的
    int numa_id = (server_num + 1) % 2;
    // 每组的数量
    int group_size = 2;
    // 当前组号，0、1在0组，2、3在1组
    int group_id = server_num / group_size;

    // 下面进行连接
    // 测试一下初始化
    struct orcl_context* orcl_ctx = orcl_context_init(server_num,group_id,4,2,group_size,1,port_index,numa_id,NULL,M_2,16*server_num+1,NULL,0);

    // 初始化一下缓冲区
    memset((void *)orcl_ctx->message_buffer, 0, orcl_ctx->message_buffer_size);

    // 测试forward转发的功能，引入4个进程，0、1、2、3，分别在两个网卡上
    // port_index0:0、2    port_index1:1、3
    // 0、1是一组，2、3是一组，我们将forward数据从0发到1
    if(server_num == 0){

        char *buf = (char *)orcl_ctx->rc_forward_buf[1];

        buf[0] = 'c';
        // 发送测试
        // void orcl_inner_group_rdma_forward(struct orcl_context* orcl_ctx, int forward_buf_index, int dest_inner_group_index, int source_offset, int dest_offset, int size);
        orcl_inner_group_rdma_forward(orcl_ctx, 1, 1, 0, 0, 64);

        sleep(1);
        orcl_publish_ready("finish1");

    }else if(server_num == 1){
        orcl_wait_till_ready("finish1");

        char *buf = (char *)orcl_ctx->message_buffer;

        if(buf[0] == 'c'){
            printf("传输正确\n");
        }else{
            printf("传输不正确\n");
        }
    }else{
        orcl_wait_till_ready("finish1");
    }

    // 迭代测试，传输65536次，看看是否可以成功传输
    

    if(server_num == 0){
        int i;
        uint64_t seed = 0xdeadbeef;
        // 这是随机数
        for (i = 0; i < server_num * 1000000; i++)
        {
            // 一个血妈神奇的随机数生成机制，最后生成的随机数要放在seed中
            orcl_fastrand(&seed);
        }

        for(i = 0; i < 65536; i++){
            int _size = (int)(orcl_fastrand(&seed) % 511 + 1);
            int _offset = (int)((orcl_fastrand(&seed) % (orcl_ctx->message_buffer_size - _size)) / 512) * 512;

            orcl_inner_group_rdma_forward(orcl_ctx, 1, 1, _offset, _offset, _size);
        }

        sleep(3);
        printf("大量发送完成\n");

        orcl_publish_ready("finish2");
    }else{
        orcl_wait_till_ready("finish2");
    }

    // 这里测试从dci到dct之间的测试
    // 从0发到2
    if(server_num == 0){
        char *buf = (char *)orcl_ctx->message_buffer;
        buf[0] = 'd';
        orcl_dci_rdma_write(orcl_ctx, 1, 0, 0, 64);

        sleep(1);
        orcl_publish_ready("finish3");

    }else if(server_num == 2){
        // 查看其转发dct缓冲区
        char *buf = (char *)orcl_ctx->dct_forward_buf[0];
        orcl_wait_till_ready("finish3");

        if(buf[0] == 'd'){
            printf("跨组传输成功\n");
        }else{
            printf("传输不成功\n");
        }

    }else{
        orcl_wait_till_ready("finish3");
    }

    // 这里执行大量随机发送
    if(server_num == 0){
        int i;
        uint64_t seed = 0xdeadbeef;
        // 这是随机数
        for (i = 0; i < server_num * 1000000; i++)
        {
            // 一个血妈神奇的随机数生成机制，最后生成的随机数要放在seed中
            orcl_fastrand(&seed);
        }

        for(i = 0; i < 65536; i++){
            int _size = (int)(orcl_fastrand(&seed) % 511 + 1);
            int _offset = (int)((orcl_fastrand(&seed) % (FORWARD_DCT_BUF_SIZE - _size)) / 512) * 512;

            orcl_dci_rdma_write(orcl_ctx, 1, _offset, _offset, _size);
        }

        sleep(3);
        printf("大量dc发送完成\n");

        orcl_publish_ready("finish4");
    }else{
        orcl_wait_till_ready("finish4");
    }
    
    
    
    return 1;
}